﻿#include <iostream>
#include <string>
#include <list>
#include <vector>
using namespace std;
class AbstractoTeam
{
protected:
  string m_name;
  AbstractoTeam *m_parent = nullptr;

public:
  AbstractoTeam(const string &name)
  {
    m_name = name;
  }
  void setParent(AbstractoTeam *parent)
  {
    m_parent = parent;
  }
  AbstractoTeam *getParent()
  {
    return m_parent;
  }
  string getName()
  {
    return m_name;
  }
  bool hasChild()
  {
    return (m_parent != nullptr);
  }
  virtual void fight() = 0;
  virtual void display() = 0;
};
class LeafTeam : public AbstractoTeam
{
public:
  using AbstractoTeam::AbstractoTeam;
  void fight() override
  {
    cout << m_parent->getName() << "下属的" << m_name << "正在战斗！" << endl;
  }
  void display() override
  {
    cout << "我是" << m_parent->getName() << "下属的" << m_name << endl;
  }
  ~LeafTeam()
  {
    cout << "我是" << m_parent->getName() << "下属的" << m_name << "\t战斗已经结束..." << endl;
  }
};
class ManagerTeam : public AbstractoTeam
{
private:
  list<AbstractoTeam *> m_children;

public:
  using AbstractoTeam::AbstractoTeam;
  void fight() override
  {
    cout << m_name << "准备战斗！" << endl;
  }
  void add(AbstractoTeam *team)
  {
    team->setParent(this);
    m_children.push_back(team);
  }
  void remove(AbstractoTeam *team)
  {
    team->setParent(nullptr);
    m_children.remove(team);
  }
  list<AbstractoTeam *> getChildren()
  {
    return m_children;
  }
  void display()
  {
    string info = string();
    for (const auto item : m_children)
    {
      if (item == m_children.back())
      {
        info += item->getName();
      }
      else
      {
        info += item->getName() + ",";
      }
    }
    cout << m_name << "的船队是【" << info << "】" << endl;
  }
};
int main()
{
  vector<string> nameList = {"黑猫团", "野狗团", "蓝豹团", "八宝团", "飞雁团"};
  ManagerTeam *root = new ManagerTeam("中国美团");
  for (int i = 0; i < nameList.size(); ++i)
  {
    ManagerTeam *child = new ManagerTeam(nameList.at(i));
    for (int j = 0; j < 3; ++j)
    {
      ManagerTeam *grandson = new ManagerTeam(child->getName() + "旗下番号" + to_string(j + 1));
      child->add(grandson);
    }
    root->add(child);
  }

  AbstractoTeam *leaf01 = new LeafTeam("卫衣团");
  root->add(leaf01);
  for (auto &item : root->getChildren())
  {
    item->display();
  }
  return 0;
}
